﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using log4net;
using System.Configuration;
using System.Xml;
using System.Text.RegularExpressions;
using System.IO;

namespace RTUDataAcquisition.AppCode
{
    /// <summary>
    /// Logging Class
    /// </summary>
    public class Logging
    {
        #region Log
        //private static string _LogConfig = System.Configuration.ConfigurationSettings.AppSettings["LogLevel"];
        private static ELogType _DebugLevel = ELogType.Debug;
        public static ELogType DebugLevel
        {
            get { return _DebugLevel; }
            set { _DebugLevel = value; }
        }
        /// <summary>
        /// Log
        /// Record [level] and [unusual]
        /// </summary>
        /// <param name="LogAddress">Wrong address</param>
        /// <param name="exp">Exception of the like</param>
        public static void SaveLog(ELogLayer LogAddress, Exception exp)
        {
            string strErrMsg = exp.Message + ",\r\n";
            strErrMsg = strErrMsg + "Source:" + exp.Source.ToString() + ",\r\n";
            strErrMsg = strErrMsg + "StackTrace:" + exp.StackTrace;
            LogContent Log = new LogContent(strErrMsg, LogAddress);
            SaveLog(Log);
        }

        /// <summary>
        /// Log
        /// Record [level] and [unusual]
        /// </summary>
        /// <param name="LogAddress">Wrong address</param>
        /// <param name="Message">Error Messages</param>
        public static void SaveLog(ELogLayer LogAddress, string Message)
        {
            LogContent Log = new LogContent(Message, LogAddress);
            SaveLog(Log);
        }

        /// <summary>
        /// Log
        /// Record [error level], [error message], [log type]
        /// </summary>
        /// <param name="LogAddress">Wrong address</param>
        /// <param name="Message">Error Messages</param>
        /// <param name="LogType">Log Type</param>
        public static void SaveLog(ELogLayer LogAddress, string Message, ELogType LogType)
        {
            LogContent Log = new LogContent(Message, LogAddress);
            if (LogType == ELogType.Data)
            { 
                ExportLog(LogType, Message); 
            }
            else
            {
                ExportLog(LogType, Log.GetMessage());
            }
        }

        /// <summary>
        /// Log
        /// Record [error message], [log type]
        /// </summary>
        /// <param name="Message">Error Messages</param>
        /// <param name="LogType">>Log Type</param>
        public static void SaveLog(string Message, ELogType LogType)
        {
            ExportLog(LogType, Message);
        }

        /// <summary>
        /// Log
        /// Record [LogContent of like]
        /// </summary>
        /// <param name="Log">LogContent of like</param>
        private static void SaveLog(LogContent Log)
        {
            ExportLog(Log.LogType, Log.GetMessage());
        }

        #endregion

        /// <summary>
        /// log dictionary
        /// </summary>
        /// <param name="LogType">log type</param>
        /// <param name="Message">log message</param>
        private static void ExportLog(ELogType LogType, string Message)
        {
            string LoggerName = "DebugLog";
            if (LogType == ELogType.Fatal)
            {
                LoggerName = "FatalLog";
                LogManager.Exists(LoggerName).Fatal(Message);
            }
            else if (LogType == ELogType.Error)
            {
                LoggerName = "ErrorLog";
                LogManager.Exists(LoggerName).Error(Message);
            }
            else if (LogType == ELogType.Warn)
            {
                LoggerName = "WarnLog";
                LogManager.Exists(LoggerName).Warn(Message);
            }
            else if (LogType == ELogType.Debug)
            {
                LoggerName = "DebugLog";
                LogManager.Exists(LoggerName).Debug(Message);
            }
            else if (LogType == ELogType.Info)
            {
                LoggerName = "InfoLog";
                LogManager.Exists(LoggerName).Info(Message);
            }
            else if (LogType == ELogType.Data)
            {
                LoggerName = "DataLog";
                LogManager.Exists(LoggerName).Info(Message);
            }
        }

        //static public log4net.Appender.FileAppender GetFileLogger()
        //{
        //    int appCounts = LogManager.GetLoggerRepository().GetAppenders().Length;
        //    string LogFileName = string.Empty;
        //    for (int i = 0; i < appCounts; i++)
        //    {
        //        log4net.Appender.FileAppender fileApp = LogManager.GetLoggerRepository().GetAppenders()[i] as log4net.Appender.FileAppender;
        //        if (fileApp != null)
        //        {
        //            return fileApp;
        //        }
        //    }
        //    return null;
        //}

        //[Obsolete]
        //static void CloseLogFile()
        //{
        //    log4net.Appender.FileAppender FileApp = GetFileLogger();
        //    FileApp.LockingModel.CloseFile();
        //}

        //[Obsolete]
        //static void OpenLogFile()
        //{
        //    log4net.Appender.FileAppender FileApp = GetFileLogger();
        //    FileApp.LockingModel.OpenFile(FileApp.File, true, Encoding.Unicode);
        //}

        //static string GetLogFileContents()
        //{
        //    log4net.Appender.FileAppender obj = GetFileLogger();
        //    string logcontents = string.Empty;
        //    string logfilename = string.Empty;
        //    CloseLogFile();
        //    try
        //    {
        //        logfilename = obj.File;
        //        logcontents = File.ReadAllText(logfilename);

        //        int index = 0;
        //        if (logcontents.LastIndexOf("\r\n\r\n") > 0)
        //        {
        //            index = logcontents.LastIndexOf("\r\n\r\n");
        //        }

        //        logcontents = logcontents.Substring(index).Replace("\r\n\r\n", "");
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine(" InnerGetLogFileContents erro: " + ex.Message);
        //        throw ex;
        //    }
        //    OpenLogFile();
        //    return logcontents;
        //}

    }

    /// <summary>
    /// Log Content Class
    /// </summary>
    public class LogContent
    {
        public LogContent()
        {
        }
        /// <summary>
        /// Log Content
        /// </summary>
        /// <param name="strMessage">Message</param>
        /// <param name="LogAddress">Address</param>
        public LogContent(string strMessage, ELogLayer LogAddress)
        {
            this._LogMessage = strMessage;
            this._LogAddress = LogAddress;
        }

        private string _LogMessage = string.Empty;

        /// <summary>
        /// Log Message Attribute
        /// </summary>
        public string LogMessage
        {
            get { return this._LogMessage; }
            set { this._LogMessage = value; }
        }

        private ELogLayer _LogAddress;
        /// <summary>
        /// Log Address Attribute
        /// </summary>
        public ELogLayer LogAddress
        {
            get { return this._LogAddress; }
            set { this._LogAddress = value; }
        }

        private ELogType _LogType = ELogType.Debug;
        /// <summary>
        /// Log Type Attribute
        /// </summary>
        public ELogType LogType
        {
            get { return this._LogType; }
            set { this._LogType = value; }
        }
        /// <summary>
        /// the string is Log Message
        /// </summary>
        /// <returns></returns>
        public string GetMessage()
        {
            string err = "Layer: " + this.LogAddress.ToString() +
               " \r\nMessage: " + this.LogMessage;

            return err;
        }
    }

    /// <summary>
    /// Log Type Enum
    /// </summary>
    public enum ELogType
    {
        /// <summary>
        /// Fatal
        /// </summary>
        Fatal,
        /// <summary>
        /// Error
        /// </summary>
        Error,
        /// <summary>
        /// Warn
        /// </summary>
        Warn,
        /// <summary>
        /// Debug
        /// </summary>
        Debug,
        /// <summary>
        /// Info
        /// </summary>
        Info,
        /// <summary>
        /// Data
        /// </summary>
        Data
    }

    /// <summary>
    /// Log Layer Enum
    /// </summary>
    public enum ELogLayer
    {
        /// <summary>
        /// ORM
        /// </summary>
        ORM,
        /// <summary>
        /// Entity
        /// </summary>
        Entity,
        /// <summary>
        /// BR
        /// </summary>
        BusinessRule,
        /// <summary>
        /// UI
        /// </summary>
        UI,
        /// <summary>
        /// Util
        /// </summary>
        Util,
        /// <summary>
        /// DB
        /// </summary>
        DB
    }
}
